home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
usenet
/
sources
/
volume91
/
graphics
/
gifmach0
/
part01
/
Sources
/
giftosham.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-02-07
|
5KB
|
227 lines
/* Copyright 1990 by Christopher A. Wichura.
See file GIFMachine.doc for full description of rights.
*/
#include "GIFMachine.h"
extern struct GIFdescriptor gdesc;
EXTERNBITPLANE;
extern char *AbortMsg;
extern BOOL Laced;
UWORD *SHAMmem;
struct RGB Palette[16];
extern UBYTE PaletteBuf[MAXCOLOURS];
extern ULONG ColourBuf[MAXCOLOURS];
static ULONG ErrBuf[MAXCOLOURS];
#define ISLACED (Laced && (y != gdesc.gd_Height - 1))
void GIFtoSHAM(void)
{
register UWORD x;
register UWORD current;
register int index;
register int index2;
ULONG error;
UWORD y;
int Pal;
int ShamIndex;
int colours;
ULONG TotalErr, LineErr;
ULONG bestpal;
ULONG besterr;
UBYTE CurrentRed, CurrentGreen, CurrentBlue;
UBYTE PreviousRed, PreviousGreen, PreviousBlue;
MyPrintf("...Converting to SHAM format.\n......Line");
ShamIndex = TotalErr = 0;
/* palette zero is always the background colour. regardless of
what the GIF specified for the background, we always use black.
this is a kludge to get around a hardware `feature' that causes
all overscanned screens to have a black background regardless
of what the background was specified to be.
*/
Palette[0].rgb_Red = Palette[0].rgb_Green = Palette[0].rgb_Blue = 0;
for (y = 0; y < gdesc.gd_Height; y += (ISLACED ? 2 : 1)) {
if (ISLACED)
MyPrintf("s %5ld-%5ld", y, y + 1);
else
MyPrintf(" %5ld", y);
if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
MyPrintf("\n%s", AbortMsg);
MyExit(ABORTEXITVAL);
}
memset((char *)ColourBuf, 0, sizeof(ColourBuf));
for (colours = index2 = 0; index2 < (ISLACED ? 2 : 1); index2++)
for (x = 0; x < gdesc.gd_Width; x++) {
current = GetValue(x, y + index2);
if (ColourBuf[current]++ == 0)
colours++;
}
MyPrintf(", %4ld unique colours", colours);
memset((char *)PaletteBuf, 0, sizeof(PaletteBuf));
for (index = 0; index < MAXCOLOURS; index++) {
if (ColourBuf[index] == 0)
continue;
ErrBuf[index] = RGBdiff(GetRed(index),
GetGreen(index),
GetBlue(index),
Palette[0].rgb_Red,
Palette[0].rgb_Green,
Palette[0].rgb_Blue);
}
for (Pal = 1; Pal < 16; Pal++) {
for (besterr = index = 0; index < MAXCOLOURS; index++) {
if (ColourBuf[index] == 0)
continue;
if (ErrBuf[index] * ColourBuf[index] >= besterr) {
bestpal = index;
besterr = ErrBuf[index] * ColourBuf[index];
}
}
Palette[Pal].rgb_Red = GetRed(bestpal);
Palette[Pal].rgb_Green = GetGreen(bestpal);
Palette[Pal].rgb_Blue = GetBlue(bestpal);
for (index = 0; index < MAXCOLOURS; index++) {
if (ColourBuf[index] == 0)
continue;
error = RGBdiff(GetRed(index),
GetGreen(index),
GetBlue(index),
Palette[Pal].rgb_Red,
Palette[Pal].rgb_Green,
Palette[Pal].rgb_Blue);
if (error < ErrBuf[index]) {
ErrBuf[index] = error;
PaletteBuf[index] = Pal;
}
}
}
for (index = 0; index < 16; index++)
SHAMmem[ShamIndex++] = (UWORD)(
Palette[index].rgb_Red << 8 |
Palette[index].rgb_Green << 4 |
Palette[index].rgb_Blue);
for (index2 = 0; index2 < (ISLACED ? 2 : 1); index2++) {
PreviousRed = Palette[0].rgb_Red;
PreviousGreen = Palette[0].rgb_Green;
PreviousBlue = Palette[0].rgb_Blue;
for (LineErr = x = 0; x < gdesc.gd_Width; x++) {
current = GetValue(x, y + index2);
CurrentRed = GetRed(current);
CurrentGreen = GetGreen(current);
CurrentBlue = GetBlue(current);
besterr = ErrBuf[current];
bestpal = PaletteBuf[current];
error = RGBdiff(
CurrentRed,
CurrentGreen,
CurrentBlue,
CurrentRed,
PreviousGreen,
PreviousBlue);
if (error < besterr) {
besterr = error;
bestpal = 16;
}
error = RGBdiff(
CurrentRed,
CurrentGreen,
CurrentBlue,
PreviousRed,
CurrentGreen,
PreviousBlue);
if (error < besterr) {
besterr = error;
bestpal = 17;
}
error = RGBdiff(
CurrentRed,
CurrentGreen,
CurrentBlue,
PreviousRed,
PreviousGreen,
CurrentBlue);
if (error < besterr) {
besterr = error;
bestpal = 18;
}
if (bestpal < 16) {
PutValue(x, y + index2, bestpal);
PreviousRed = Palette[bestpal].rgb_Red;
PreviousGreen = Palette[bestpal].rgb_Green;
PreviousBlue = Palette[bestpal].rgb_Blue;
} else if (bestpal == 16) {
PutValue(x, y + index2, CurrentRed | 0x20);
PreviousRed = CurrentRed;
} else if (bestpal == 17) {
PutValue(x, y + index2, CurrentGreen | 0x30);
PreviousGreen = CurrentGreen;
} else {
PutValue(x, y + index2, CurrentBlue | 0x10);
PreviousBlue = CurrentBlue;
}
LineErr += besterr;
}
TotalErr += LineErr;
}
MyPrintf("\x9B" "%sD\x9BK", (ISLACED ? "34" : "27"));
}
{
ULONG ErrPerPixel;
char TextBuf[10];
ErrPerPixel = ((TotalErr / gdesc.gd_Height) * 1000) / gdesc.gd_Width;
MySPrintf(TextBuf, "%ld.%03ld", ErrPerPixel / 1000, ErrPerPixel % 1000);
MyPrintf("\x9B" "4DTotal colour error = %ld, Mean per line = %ld, Per pixel = %s.\n",
TotalErr, TotalErr / gdesc.gd_Height, TextBuf);
}
}